﻿package com.singlenotion.display.sliders 
{
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import gs.easing.Elastic;
	import gs.easing.Sine;
	import gs.TweenLite;
	import gs.TweenMax;
	
	/**
	 * ...
	 * @author Adam Jowett (Single Notion)
	 */
	public class VerticalSlider extends MovieClip
	{
		private var _items:Array;
		private var _sliderWidth:Number;
		private var _sliderHeight:Number;
		private var _topArrow:Sprite;
		private var _bottomArrow:Sprite;
		private var _sliderHolder:Sprite;
		private var _showMask:Boolean;
		private var _maskBuffer:Number;
		private var _showArrows:Boolean;
		private var _arrowColour:int;
		private var _arrowOverColour:int;
		private var _topArrowBuffer:Number;
		private var _bottomArrowBuffer:Number;
		private var _arrowHorizontalOffset:Number;
		private var _currentID:int;
		private var _tweenTime:Number;
		
		public function VerticalSlider(	$items:Array, $width:Number, $height:Number, $tweenTime:Number = 0.6, $showmask:Boolean = false, $showArrows:Boolean = true, 
										$maskBuffer:Number = 0, $arrowColour:int = 0xFFFFFF, $arrowOverColour:int = 0x00CC33, $leftArrowBuffer:Number = 5, 
										$rightArrowBuffer:Number = 5, $arrowHorizontalOffset:Number = 0) 
		{
			_items = $items;
			_sliderWidth = $width;
			_sliderHeight = $height;
			_showMask = $showmask;
			_maskBuffer = $maskBuffer;
			_showArrows = $showArrows;
			_arrowColour = $arrowColour;
			_arrowOverColour = $arrowOverColour;
			_topArrowBuffer = $leftArrowBuffer;
			_bottomArrowBuffer = $rightArrowBuffer;
			_arrowHorizontalOffset = $arrowHorizontalOffset;
			_tweenTime = $tweenTime;
			
			addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
		}
		
		/**********************************************************************************/
				
		protected function init($e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			addEventListener(Event.REMOVED_FROM_STAGE, destroy, false, 0, true);
			
			_currentID = 0;
			
			build();
		}
		
		public function destroy($e:Event):void
		{
			removeEventListener(Event.REMOVED_FROM_STAGE, destroy);
		}
		
		/***********************************************************************************/
		
		private function build():void
		{
			_sliderHolder = new Sprite();
			addChild(_sliderHolder);
			
			var totalHeight:Number = 0;
			
			for each (var item:* in _items)
			{
				_sliderHolder.addChild(item);
				item.y = totalHeight;
				
				totalHeight += _sliderHeight;
			}
			
			if (_showArrows) addArrows();
			if (_showMask) addMask();
			
			goto(1);
			
			dispatchEvent(new Event(SliderEvents.CREATED, true, true));
		}
		
		private function addArrows():void
		{
			var lineWidth:Number = 3;
			var arrowWidth:Number = 22;
			var arrowHeight:Number = 8;
			
			_topArrow = new Sprite();
			_topArrow.graphics.clear();
			_topArrow.graphics.beginFill(0x990000, 0);
			_topArrow.graphics.drawRect(0, 0, arrowWidth + lineWidth, arrowHeight);
			_topArrow.graphics.endFill();
			_topArrow.graphics.lineStyle(lineWidth, _arrowColour);
			_topArrow.graphics.moveTo(0, arrowHeight);
			_topArrow.graphics.lineTo(arrowWidth / 2, 0);
			_topArrow.graphics.lineTo(arrowWidth, arrowHeight);
			
			_topArrow.buttonMode = true;
			_topArrow.x = _sliderWidth / 2 - _topArrow.width / 2 + _arrowHorizontalOffset;
			_topArrow.y = _topArrow.height + _topArrowBuffer;
			
			_bottomArrow = new Sprite();
			_bottomArrow.graphics.clear();
			_bottomArrow.graphics.beginFill(0x990000, 0);
			_bottomArrow.graphics.drawRect(0, 0, arrowWidth + lineWidth, arrowHeight);
			_bottomArrow.graphics.endFill();
			_bottomArrow.graphics.lineStyle(lineWidth, _arrowColour);
			_bottomArrow.graphics.lineTo(arrowWidth / 2, arrowHeight);
			_bottomArrow.graphics.lineTo(arrowWidth, 0);
			
			_bottomArrow.buttonMode = true;
			_bottomArrow.x = _topArrow.x;
			_bottomArrow.y = _sliderHeight - _bottomArrow.height - _bottomArrowBuffer;
			
			addChild(_topArrow);
			addChild(_bottomArrow);
			
			adjustArrows();
		}
		
		private function topArrowListener($e:MouseEvent):void 
		{
			_topArrow.removeEventListener(MouseEvent.CLICK, topArrowListener);
			_currentID--;
			goto(_currentID + 1);
		}
		
		private function bottomArrowListener($e:MouseEvent):void 
		{
			_bottomArrow.removeEventListener(MouseEvent.CLICK, bottomArrowListener);
			_currentID++;
			goto(_currentID + 1);
		}
		
		private function adjustSlider():void
		{
			if (_showArrows) adjustArrows();
			dispatchEvent(new Event(SliderEvents.SLIDE_COMPLETE, true, true));
		}
		
		private function adjustArrows():void
		{
			_topArrow.addEventListener(MouseEvent.ROLL_OVER, arrowOverListener, false, 0, true);
			_topArrow.addEventListener(MouseEvent.ROLL_OUT, arrowOutListener, false, 0, true);
			_topArrow.addEventListener(MouseEvent.CLICK, topArrowListener, false, 0, true);
			
			_bottomArrow.addEventListener(MouseEvent.ROLL_OVER, arrowOverListener, false, 0, true);
			_bottomArrow.addEventListener(MouseEvent.ROLL_OUT, arrowOutListener, false, 0, true);
			_bottomArrow.addEventListener(MouseEvent.CLICK, bottomArrowListener, false, 0, true);
			
			_topArrow.visible = _currentID > 0; // _sliderHolder.y < 0;
			_bottomArrow.visible = _currentID < _items.length; //(_sliderHolder.x > -(_sliderWidth * (_items.length - 1)));
		}
		
		private function arrowOverListener($e:MouseEvent):void 
		{
			TweenLite.to($e.target, 0.3, { tint:_arrowOverColour } );
		}
		
		private function arrowOutListener($e:MouseEvent):void 
		{
			TweenLite.to($e.target, 0.3, { removeTint:true } );
		}
		
		private function addMask():void
		{
			var sliderMask:Sprite = new Sprite();
			sliderMask.graphics.clear();
			sliderMask.graphics.beginFill(0x990000, 0.5);
			sliderMask.graphics.drawRect(0, 0, _sliderWidth - (_maskBuffer * 2), _sliderHeight);
			sliderMask.graphics.endFill();
			sliderMask.x = _maskBuffer;
			
			addChild(sliderMask);
			
			_sliderHolder.mask = sliderMask;
		}
		
		public function getItem($id:int):* { return _items[$id]; }
		
		public function getCurrentItem():* { return _items[_currentID]; }
		
		public function goto($id:int):void
		{
			var index:int = $id - 1;
			
			dispatchEvent(new Event(SliderEvents.SLIDE_BEGIN, true, true));
			
			var i:int;
			var l:int = _items.length;
			for (i = 0; i < l; i++) {
				if (i == index) {
					TweenMax.to(_items[i], _tweenTime, { autoAlpha:1, blurFilter: { blurX:0, blurY:0 }, colorMatrixFilter: { colorize:0x000000, amount:0 } } );
				} else if (i == index + 1) {
					TweenMax.to(_items[i], _tweenTime, { autoAlpha:1, blurFilter: { blurX:5, blurY:5 }, colorMatrixFilter: { colorize:0x000000, amount:0.7 } } );
				} else {
					TweenLite.to(_items[i], _tweenTime, { autoAlpha:0, blurFilter: { blurX:5, blurY:5 } } );
				}
			}
			
			TweenLite.to(_sliderHolder, _tweenTime, { y: -(_sliderHeight * ($id - 1)), onComplete:adjustSlider } );
			
			_currentID = $id - 1;
		}
		
		public function get currentID():int { return _currentID; }
		
		public function get items():Array { return _items; }
	}
	
}